home *** CD-ROM | disk | FTP | other *** search
/ Delphi 2 - Developers' Solutions / Delphi 2 Developers' Solutions.iso / dds / chap11 / howto03 / delphi10 / cciccpop.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-06-12  |  40.6 KB  |  1,139 lines

  1. unit Cciccpop;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  7.   Forms, Dialogs, ExtCtrls, StdCtrls, Buttons, Menus, FileCtrl, CCWSock, CCICCInf,
  8.   CCICCPrf, IniFiles, Gauges , CCUUCode, CCiccfrm;
  9.  
  10. type
  11.   { Component To Hold POP3/SMTP handling capabilities }
  12.   TPOP3SMTPComponent = class( TWinControl )
  13.   public
  14.     POP3CommandInProgress ,
  15.     Connection_Established : Boolean;
  16.     Socket1 : TCCSocket;
  17.     constructor Create( AOwner : TComponent ); override;
  18.     destructor Destroy; override;
  19.     function EstablishPOP3Connection( PCRPointer : PConnectionsRecord ) : Boolean;
  20.     function POP3Disconnect : Boolean;
  21.     function DoCStyleFormat(       TheText      : string;
  22.                              const TheArguments : array of const ) : String;
  23.     procedure UpdateGauge( BytesFinished , TotalToHandle : longint );
  24.     procedure AddProgressText( WhatText : String );
  25.     procedure ShowProgressText( WhatText : String );
  26.     procedure ShowProgressErrorText( WhatText : String );
  27.     function GetPOP3ServerResponse( var ResponseString : String ) : integer;
  28.     procedure POP3SMTPSocketsErrorOccurred( Sender     : TObject;
  29.                                      ErrorCode  : Integer;
  30.                                      TheMessage : String   );
  31.     function PerformPOP3Command(
  32.                     TheCommand   : string;
  33.               const TheArguments : array of const ) : Integer;
  34.     function PerformPOP3ExtendedCommand(
  35.                     TheCommand   : string;
  36.               const TheArguments : array of const ) : Integer;
  37.     function GetPOP3ServerExtendedResponse( ResponseString : PChar ) : integer;
  38.     function GetNextSDItem(     WorkingString : String;
  39.                             var TheIndex      : Integer ) : String;
  40.     procedure PurgeTrashedMessageListings( TheEMBRecord : PEMailMailBoxRecord );
  41.     procedure TrashMessage( TheEMMRecord : PEMailMessageRecord );
  42.     procedure TrashAllMarkedMessages( TheLB       : TListBox;
  43.                                       TheMBRecord : PEMailMailboxRecord );
  44.     procedure ParseMailListing(     TheListing : String;
  45.                                 var TotalMessages : Longint;
  46.                                 var MessageBytes : Longint);
  47.     function CheckAllNewMail( var TotalBytes : Longint ) : Integer;
  48.     function GetMessageHeader( TheReturnList : TStringList ) : Longint;
  49.     function DownloadMessageListing( TheNumber   : Integer;
  50.                                      TheFileName : String;
  51.                                      TheHeaderSL : TStringList ) : Longint;
  52.     function DownloadAllMessageListings( TheEMBRecord : PEMailMailBoxRecord ) : Boolean;
  53.     function GetHeaderSubject( HList : TStringList ) : String;
  54.     function GetHeaderSender( HList : TStringList ) : String;
  55.     function GetHeaderRecipient( HList : TStringList ) : String;
  56.     function GetHeaderCarbons( HList : TStringList ) : String;
  57.     function GetHeaderBlindCarbons( HList : TStringList ) : String;
  58.     function GetHeaderDateTime( HList : TStringList ) : String;
  59.     procedure TransferMessage( SourceEMBRecord , TargetEMBRecord : PEMailMailBoxRecord;
  60.                               MessageNumber : Integer );
  61.     function LoginUser( PCRPointer : PConnectionsRecord ) : Boolean;
  62.     function SendPassword( PCRPointer : PConnectionsRecord ) : Boolean;
  63.     function DeleteMailItem( TheNumber : Longint ) : Boolean;
  64.   end;
  65.  
  66. var
  67.   ThePOP3SMTPComponent  : TPOP3SMTPComponent; { Gee, which one is this? :) }
  68.  
  69. implementation
  70.  
  71. procedure TPOP3SMTPComponent.TrashMessage( TheEMMRecord : PEMailMessageRecord );
  72. begin
  73.   TheEMMRecord^.MRMessageSender := 'DELETE ME';
  74. end;
  75.  
  76. procedure TPOP3SMTPComponent.TrashAllMarkedMessages( TheLB       : TListBox;
  77.                                                      TheMBRecord : PEMailMailboxRecord );
  78. var Counter_1 : Integer;
  79.     WorkingList : TList;
  80. begin
  81.   WorkingList := TList( TheMBRecord^.MBLTag );
  82.   for Counter_1 := 0 to TheLB.Items.Count - 1 do
  83.   begin
  84.     if TheLB.Selected[ Counter_1 ] then
  85.     begin
  86.       TrashMessage( PEMailMessageRecord( WorkingList.Items[ Counter_1 ] ));
  87.     end;
  88.   end;
  89. end;
  90.  
  91. { This function calls an extended response POP3SMTP command routine }
  92. function TPOP3SMTPComponent.PerformPOP3ExtendedCommand(
  93.                TheCommand   : string;
  94.          const TheArguments : array of const ) : Integer;
  95. var TheBuffer : string; { Text buffer }
  96. begin
  97.   { If command in progress send back -1 error }
  98.   if POP3CommandInProgress then
  99.   begin
  100.     Result := -1;
  101.     exit;
  102.   end;
  103.   { Set status variable }
  104.   POP3CommandInProgress := True;
  105.   { Set global error code }
  106.   GlobalErrorCode := 0;
  107.   { Format output string }
  108.   TheBuffer := Format( TheCommand , TheArguments );
  109.   { Preset failure code }
  110.   Result := TCPIP_STATUS_FATAL_ERROR;
  111.   { If invalid socket or no connection abort }
  112.   if ( Socket1.TheSocket = INVALID_SOCKET ) or not Connection_Established then
  113.    exit;
  114.   { Send the buffer plus EOL chars }
  115.   Socket1.StringData := TheBuffer + #13#10;
  116.   { if abort due to timeout or other error exit }
  117.   if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then exit;
  118.   { Otherwise return preliminary code }
  119.   Result := TCPIP_STATUS_PRELIMINARY;
  120. end;
  121.  
  122. { This function gets an extended period-ended multiline response from the server }
  123. function TPOP3SMTPComponent.GetPOP3ServerExtendedResponse( ResponseString : PChar ) : integer;
  124. var
  125.   { Assume ResponseString already allocated as 0..513 }
  126.   { Pointer to the response string }
  127.   TheBuffer ,
  128.   BufferPointer : array[0..255] of char;
  129.   HolderBuffer : array[0..513] of char;
  130.   { Character to check for response code }
  131.   ResponseChar   : char;
  132.   { Pointers into returned string }
  133.   TheIndex ,
  134.   TheLength     : integer;
  135.   { Control variable }
  136.   LeftoversInPan ,
  137.   Finished      : Boolean;
  138.   BufferString : String;
  139. begin
  140.   { Preset fatal error }
  141.   Result := TCPIP_STATUS_FATAL_ERROR;
  142.   { Start loop control }
  143.   LeftoversInPan := false;
  144.   Finished := false;
  145.   StrCopy( HolderBuffer , '' );
  146.   repeat
  147.     { Do a peek }
  148.     BufferString := Socket1.PeekData;
  149.     { If timeout or other error exit }
  150.     if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then exit;
  151.     { Find end of line character }
  152.     TheIndex := Pos( #10 , BufferString );
  153.     if TheIndex = 0 then
  154.     begin
  155.       TheIndex := Pos( #13 , BufferString );
  156.       if TheIndex = 0 then
  157.       begin
  158.         TheIndex := Pos( #0 , BufferString );
  159.         if TheIndex = 0 then
  160.         begin
  161.           TheIndex := Length( BufferString );
  162.           LeftoversInPan := True;
  163.           StrPCopy( TheBuffer , BufferString );
  164.           StrCat( HolderBuffer , TheBuffer );
  165.           LeftoversOnTable := false;
  166.         end;
  167.       end;
  168.     end;
  169.     { If an end of line then process the line }
  170.     if TheIndex > 0 then
  171.     begin
  172.       { Get length of string }
  173.       TheLength := TheIndex;
  174.       { Receive actual data }
  175.       Socket1.CCSockReceive( Socket1.TheSocket   ,
  176.                              @BufferPointer[ 0 ] ,
  177.                              TheLength              );
  178.       { Abort if timeout or error }
  179.       if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then exit;
  180.       { Put in the length byte }
  181.       BufferPointer[ TheLength ] := Chr( 0 );
  182.       if LeftOversOnTable then
  183.       begin
  184.         LeftOversOnTable := false;
  185.         StrCopy( ResponseString , HolderBuffer );
  186.         StrCat( ResponseString , BufferPointer );
  187.       end
  188.       else
  189.       begin
  190.         if not LeftoversInPan then StrCopy( ResponseString , BufferPointer );
  191.       end;
  192.       if LeftoversInPan then
  193.       begin
  194.         LeftoversInPan := false;
  195.         LeftoversOnTable := true;
  196.       end
  197.       else
  198.       begin
  199.         ResponseChar := ResponseString[ 0 ];
  200.         if (( ResponseChar = '.' ) and ( StrLen( ResponseString ) <= 3 )) then
  201.         begin
  202.           ResponseString[ 0 ] := ' ';
  203.           Finished := true;
  204.           Result := TCPIP_STATUS_COMPLETED;
  205.         end
  206.         else
  207.         begin
  208.           if ResponseChar = '.' then ResponseString[ 0 ] := ' ';
  209.           Finished := true;
  210.           Result := TCPIP_STATUS_PRELIMINARY;
  211.         end;
  212.       end;
  213.     end;
  214.   until ( Finished and ( not LeftoversOnTable ));
  215.   StrLCopy( ResponseString , ResponseString , StrLen( ResponseString ) - 2 );
  216. end;
  217.  
  218.  
  219. { This function moves along a string from an index, getting the next }
  220. { string delimited item or last one on string.                       }
  221. function TPOP3SMTPComponent.GetNextSDItem(     WorkingString : String;
  222.                                        var TheIndex      : Integer ) : String;
  223. var HoldingString : String;
  224. begin
  225.   HoldingString := Copy( WorkingString , TheIndex + 1 , 255 );
  226.   TheIndex := Pos( ' ' , HoldingString );
  227.   if TheIndex = 0 then
  228.   begin
  229.     Result := HoldingString;
  230.   end
  231.   else
  232.   begin
  233.     HoldingString := Copy( HoldingString , 1 , TheIndex - 1 );
  234.     Result := HoldingString;
  235.   end;
  236. end;
  237.  
  238. { This method assumes logged into server; gets data via STAT command }
  239. { returns total bytes in var'd param and total messages as result    }
  240. function TPOP3SMTPComponent.CheckAllNewMail( var TotalBytes : Longint ) : Integer;
  241. var TheReturnString : String;  { Internal string holder }
  242.     TheResult       : Integer; { Internal int holder    }
  243.     TheLResult      : Longint;
  244. begin
  245.   TheReturnString :=
  246.    DoCStyleFormat( 'STAT' , [ nil ] );
  247.   { Put result in progress and status line }
  248.   AddProgressText( TheReturnString );
  249.   ShowProgressText( TheReturnString );
  250.   { Begin login sequence with user name }
  251.   TheResult := PerformPOP3Command( 'STAT', [ nil ] );
  252.   if TheResult <> TCPIP_STATUS_PRELIMINARY then
  253.   begin
  254.     POP3CommandInProgress := false;
  255.     Result := -1;
  256.     exit;
  257.   end;
  258.   repeat
  259.     TheResult := GetPOP3ServerResponse( TheReturnString );
  260.     { Put result in progress and status line }
  261.     AddProgressText( TheReturnString );
  262.     ShowProgressText( TheReturnString + #13#10 );
  263.   until (( GlobalAbortedFlag ) or ( TheResult <> TCPIP_STATUS_PRELIMINARY ));
  264.   POP3CommandInProgress := false;
  265.   if ( GlobalAbortedFlag or ( TheResult <> TCPIP_STATUS_COMPLETED )) then
  266.   begin
  267.     { Do clever C formatting trick }
  268.     TheReturnString :=
  269.      DoCStyleFormat( 'Mail Not Available!' , [ nil ] );
  270.     { Put result in progress and status line }
  271.     AddProgressText( TheReturnString );
  272.     ShowProgressErrorText( TheReturnString );
  273.     { Signal error }
  274.     Result := -1;
  275.     { leave }
  276.     exit;
  277.   end;
  278.   ParseMailListing( TheReturnString , TheLResult , TotalBytes );
  279.   Result := TheLResult;
  280. end;
  281.  
  282. function TPOP3SMTPComponent.DeleteMailItem( TheNumber : Longint ) : Boolean;
  283. var TheReturnString : String;  { Internal string holder }
  284.     TheResult       : Integer; { Internal int holder    }
  285. begin
  286.   TheReturnString :=
  287.    DoCStyleFormat( 'DELE %d' , [ TheNumber ] );
  288.   { Put result in progress and status line }
  289.   AddProgressText( TheReturnString );
  290.   ShowProgressText( TheReturnString );
  291.   { Begin login sequence with user name }
  292.   TheResult := PerformPOP3Command( 'DELE %d', [ TheNumber ] );
  293.   if TheResult <> TCPIP_STATUS_PRELIMINARY then
  294.   begin
  295.     POP3CommandInProgress := false;
  296.     Result := false;
  297.     exit;
  298.   end;
  299.   repeat
  300.     TheResult := GetPOP3ServerResponse( TheReturnString );
  301.     { Put result in progress and status line }
  302.     AddProgressText( TheReturnString );
  303.     ShowProgressText( TheReturnString + #13#10 );
  304.   until (( GlobalAbortedFlag ) or ( TheResult <> TCPIP_STATUS_PRELIMINARY ));
  305.   POP3CommandInProgress := false;
  306.   if ( GlobalAbortedFlag or ( TheResult <> TCPIP_STATUS_COMPLETED )) then
  307.   begin
  308.     { Do clever C formatting trick }
  309.     TheReturnString :=
  310.      DoCStyleFormat( 'Mail Not Available!' , [ nil ] );
  311.     { Put result in progress and status line }
  312.     AddProgressText( TheReturnString );
  313.     ShowProgressErrorText( TheReturnString );
  314.     { Signal error }
  315.     Result := false;
  316.     { leave }
  317.     exit;
  318.   end;
  319.   Result := True;
  320. end;
  321.  
  322. { This method splits up a listing and pulls out its component data }
  323. procedure TPOP3SMTPComponent.ParseMailListing(     TheListing : String;
  324.                                                var TotalMessages : Longint;
  325.                                                var MessageBytes : Longint);
  326. var HoldingString ,
  327.     HoldingString2 : String;
  328.     WorkingIndex  : Integer;
  329. begin
  330.   WorkingIndex := Pos( ' ' , TheListing );
  331.   HoldingString := Copy( TheListing , WorkingIndex + 1 , 255 );
  332.   WorkingIndex := Pos(  ' ' , HoldingString );
  333.   HoldingString2 := Copy( HoldingString , 1 , WorkingIndex - 1 );
  334.   TotalMessages := StrToInt( HoldingString2 );
  335.   HoldingString := Copy( HoldingString , WorkingIndex + 1 , 255 );
  336.   WorkingIndex := Pos(  ' ' , HoldingString );
  337.   if WorkingIndex = 0 then WorkingIndex := 256;
  338.   HoldingString2 := Copy( HoldingString , 1 , WorkingIndex - 1 );
  339.   MessageBytes := StrToInt( HoldingString2 );
  340. end;
  341.  
  342. { This method accumulates all the strings until '' as a messge header }
  343. function TPOP3SMTPComponent.GetMessageHeader( TheReturnList : TStringList ) : Longint;
  344. var TheReturnString : String;  { Internal string holder }
  345.     TheResult       : Integer; { Internal int holder    }
  346.     TheReturnPChar ,
  347.     TheHoldingPChar : PChar;
  348.     TotalGotten : Longint;
  349. begin
  350.   GetMem( TheReturnPChar , 514 );
  351.   TheReturnList.Clear;
  352.   TotalGotten := 0;
  353.   repeat
  354.     TheResult := GetPOP3ServerExtendedResponse( TheReturnPChar );
  355.     if StrLen( TheReturnPChar ) < 3 then
  356.     begin
  357.      TheResult := TCPIP_STATUS_COMPLETED;
  358.     end;
  359.     TotalGotten := TotalGotten + StrLen( TheReturnPChar ) + 2;
  360.     if StrLen( TheReturnPChar ) > 255 then
  361.     begin
  362.       Getmem( TheHoldingPChar , 255 );
  363.       while StrLen( TheReturnPChar ) > 255 do
  364.       begin
  365.         StrCopy( TheHoldingPChar , '' );
  366.         StrMove( TheHoldingPChar , TheReturnPChar , 255 );
  367.         TheReturnPChar := TheReturnPChar + 256;
  368.         TheReturnString := StrPas( TheHoldingPChar );
  369.         TheReturnList.Add( TheReturnString );
  370.       end;
  371.       StrCopy( TheHoldingPChar , '' );
  372.       StrMove( TheHoldingPChar , TheReturnPChar , StrLen( TheReturnPChar ));
  373.       TheReturnString := StrPas( TheHoldingPChar );
  374.       TheReturnString := '\' + TheReturnString;
  375.       TheReturnList.Add( TheReturnString );
  376.       FreeMem( TheHoldingPChar , 255 );
  377.     end
  378.     else
  379.     begin
  380.       TheReturnString := StrPas( TheReturnPChar );
  381.       TheReturnList.Add( TheReturnString );
  382.     end;
  383.   until (( GlobalAbortedFlag ) or ( TheResult = TCPIP_STATUS_COMPLETED ));
  384.   FreeMem( TheReturnPChar , 514 );
  385.   Result := TotalGotten;
  386. end;
  387.  
  388. { This method parses a header stringlist and obtains the subject line }
  389. function TPOP3SMTPComponent.GetHeaderSubject( HList : TStringList ) : String;
  390. var Counter_1     : Integer;
  391.     Finished      : Boolean;
  392.     WorkingIndex  : Integer;
  393.     WorkingString : String;
  394. begin
  395.   Counter_1 := 0;
  396.   Finished := false;
  397.   WorkingString := '[No Subject]';
  398.   while (( not Finished ) and ( Counter_1 <= HList.Count - 1 )) do
  399.   begin
  400.     WorkingIndex := Pos( 'SUBJECT:' , Uppercase( HList.Strings[ Counter_1 ] ));
  401.     if WorkingIndex > 0 then
  402.     begin
  403.       WorkingString := Copy( HList.Strings[ Counter_1 ] , 9 , 255 );
  404.       Finished := true;
  405.     end
  406.     else Inc( Counter_1 );
  407.   end;
  408.   Result := WorkingString;
  409. end;
  410.  
  411. { This method parses a header stringlist and obtains the sender's ID }
  412. function TPOP3SMTPComponent.GetHeaderSender( HList : TStringList ) : String;
  413. var Counter_1     : Integer;
  414.     Finished      : Boolean;
  415.     WorkingIndex  : Integer;
  416.     WorkingString : String;
  417. begin
  418.   Counter_1 := 0;
  419.   Finished := false;
  420.   WorkingString := '';
  421.   while (( not Finished ) and ( Counter_1 <= HList.Count - 1 )) do
  422.   begin
  423.     WorkingIndex := Pos( 'FROM:' , Uppercase( HList.Strings[ Counter_1 ] ));
  424.     if WorkingIndex > 0 then
  425.     begin
  426.       WorkingString := Copy( HList.Strings[ Counter_1 ] , 7 , 255 );
  427.       Finished := true;
  428.     end
  429.     else Inc( Counter_1 );
  430.   end;
  431.   Result := WorkingString;
  432. end;
  433.  
  434. { This method strips out the TO: field of a mail message header }
  435. function TPOP3SMTPComponent.GetHeaderRecipient( HList : TStringList ) : String;
  436. var Counter_1     : Integer;
  437.     Finished      : Boolean;
  438.     WorkingIndex  : Integer;
  439.     WorkingString : String;
  440. begin
  441.   Counter_1 := 0;
  442.   Finished := false;
  443.   WorkingString := '';
  444.   while (( not Finished ) and ( Counter_1 <= HList.Count - 1 )) do
  445.   begin
  446.     WorkingIndex := Pos( 'TO:' , Uppercase( HList.Strings[ Counter_1 ] ));
  447.     if WorkingIndex > 0 then
  448.     begin
  449.       WorkingString := Copy( HList.Strings[ Counter_1 ] , 5 , 255 );
  450.       Finished := true;
  451.     end
  452.     else Inc( Counter_1 );
  453.   end;
  454.   Result := WorkingString;
  455. end;
  456.  
  457. { This method strips out the CC: field of a mail message header }
  458. function TPOP3SMTPComponent.GetHeaderCarbons( HList : TStringList ) : String;
  459. var Counter_1     : Integer;
  460.     Finished      : Boolean;
  461.     WorkingIndex  : Integer;
  462.     WorkingString : String;
  463. begin
  464.   Counter_1 := 0;
  465.   Finished := false;
  466.   WorkingString := '';
  467.   while (( not Finished ) and ( Counter_1 <= HList.Count - 1 )) do
  468.   begin
  469.     WorkingIndex := Pos( 'CC:' , Uppercase( HList.Strings[ Counter_1 ] ));
  470.     if WorkingIndex > 0 then
  471.     begin
  472.       WorkingString := Copy( HList.Strings[ Counter_1 ] , 5 , 255 );
  473.       Finished := true;
  474.     end
  475.     else Inc( Counter_1 );
  476.   end;
  477.   Result := WorkingString;
  478. end;
  479.  
  480. { This method strips out the BCC: field of a mail message header }
  481. function TPOP3SMTPComponent.GetHeaderBlindCarbons( HList : TStringList ) : String;
  482. var Counter_1     : Integer;
  483.     Finished      : Boolean;
  484.     WorkingIndex  : Integer;
  485.     WorkingString : String;
  486. begin
  487.   Counter_1 := 0;
  488.   Finished := false;
  489.   WorkingString := '';
  490.   while (( not Finished ) and ( Counter_1 <= HList.Count - 1 )) do
  491.   begin
  492.     WorkingIndex := Pos( 'BCC:' , Uppercase( HList.Strings[ Counter_1 ] ));
  493.     if WorkingIndex > 0 then
  494.     begin
  495.       WorkingString := Copy( HList.Strings[ Counter_1 ] , 6 , 255 );
  496.       Finished := true;
  497.     end
  498.     else Inc( Counter_1 );
  499.   end;
  500.   Result := WorkingString;
  501. end;
  502.  
  503. { This method strips out the DATE: field of a mail message header }
  504. function TPOP3SMTPComponent.GetHeaderDateTime( HList : TStringList ) : String;
  505. var Counter_1     : Integer;
  506.     Finished      : Boolean;
  507.     WorkingIndex  : Integer;
  508.     WorkingString : String;
  509. begin
  510.   Counter_1 := 0;
  511.   Finished := false;
  512.   WorkingString := '';
  513.   while (( not Finished ) and ( Counter_1 <= HList.Count - 1 )) do
  514.   begin
  515.     WorkingIndex := Pos( 'DATE:' , Uppercase( HList.Strings[ Counter_1 ] ));
  516.     if WorkingIndex > 0 then
  517.     begin
  518.       WorkingString := Copy( HList.Strings[ Counter_1 ] , 7 , 255 );
  519.       Finished := true;
  520.     end
  521.     else Inc( Counter_1 );
  522.   end;
  523.   Result := WorkingString;
  524. end;
  525.  
  526. { This method transfers a message from one mailbox to another }
  527. procedure TPOP3SMTPComponent.TransferMessage( SourceEMBRecord ,
  528.                                               TargetEMBRecord : PEMailMailBoxRecord;
  529.                                               MessageNumber : Integer );
  530. var  WorkingList1 , WorkingList2 : TList;
  531.      TheEMMRecord : PEMailMessageRecord;
  532. begin
  533.   WorkingList1 := TList( SourceEMBRecord^.MBLTag );
  534.   WorkingList2 := TList( TargetEMBRecord^.MBLTag );
  535.   TheEMMRecord := PEMailMessageRecord( WorkingList1.Items[ MessageNumber ] );
  536.   WorkingList2.Add( TheEMMRecord );
  537.   SourceEMBRecord^.MBLTag := Longint( WorkingList1 );
  538.   TargetEMBRecord^.MBLTag := Longint( WorkingList2 );
  539. end;
  540.  
  541. { This function deletes all read/sent articles and associated files }
  542. procedure TPOP3SMTPComponent.PurgeTrashedMessageListings( TheEMBRecord : PEMailMailBoxRecord );
  543. var TheEMMRecord   : PEMailMessageRecord;
  544.     Counter_1      : Integer;
  545.     WorkingList    : TList;
  546.     Finished       : Boolean;
  547. begin
  548.   { Do this for ease of coding }
  549.   with TheEMBRecord^ do
  550.   begin
  551.     { Get the current TList of article headers }
  552.     WorkingList := TList( MBLTag );
  553.     { Run up to total new articles }
  554.     for Counter_1 := 0 to WorkingList.Count - 1 do
  555.     begin
  556.       TheEMMRecord := PEMailMessageRecord( WorkingList.Items[ Counter_1 ] );
  557.       if ( TheEMMRecord^.MRMessageSender = 'DELETE ME' ) then
  558.       begin
  559.         Dec( MBTotal );
  560.         if not TheEMMRecord^.MRRead then if MBUnReadTotal > 0 then Dec( MBUnReadTotal );
  561.         if not TheEMMRecord^.MRSent then if MBUnSentTotal > 0 then Dec( MBUnSentTotal );
  562.         if FileExists( MailPath + '\' + TheEMMRecord^.MRFilename ) then
  563.          {DeleteFile( MailPath + '\' + TheEMMRecord^.MRFileName )};
  564.       end;
  565.     end;
  566.     Counter_1 := 0;
  567.     Finished := False;
  568.     if WorkingList.Count = 0 then Finished := true;
  569.     while Not Finished do
  570.     begin
  571.       TheEMMRecord := PEMailMessageRecord( WorkingList.Items[ Counter_1 ] );
  572.       if ( TheEMMRecord^.MRMessageSender = 'DELETE ME' ) then
  573.       begin
  574.         WorkingList.Delete( Counter_1 );
  575.       end
  576.       else Counter_1 := Counter_1 + 1;
  577.       if Counter_1 > WorkingList.Count - 1 then Finished := true;
  578.     end;
  579.   end;
  580. end;
  581.  
  582. { This method uses the ARTICLE command to obtain an article and put it in a  }
  583. { preset/supplied file. It is designed to work by itself or inside DAALs     }
  584. function TPOP3SMTPComponent.DownloadMessageListing( TheNumber   : Integer;
  585.                                                     TheFileName : String;
  586.                                                     TheHeaderSL : TStringList   ) : Longint;
  587. var TheReturnString : String;  { Internal string holder }
  588.     TheResult       : Integer; { Internal int holder    }
  589.     TheReturnPChar ,
  590.     TheHoldingPChar : PChar;
  591.     TheMessageFile       : TextFile;
  592.     Counter_1   : Integer;
  593.     TotalGotten : Longint;
  594. begin
  595.   TheReturnString :=
  596.    DoCStyleFormat( 'RETR %d' ,
  597.     [ TheNumber ] );
  598.   { Put result in progress and status line }
  599.   AddProgressText( TheReturnString );
  600.   ShowProgressText( TheReturnString );
  601.   { Begin login sequence with user name }
  602.   TheResult := PerformPOP3Command( 'RETR %d', [ TheNumber ] );
  603.   if TheResult <> TCPIP_STATUS_PRELIMINARY then
  604.   begin
  605.     POP3CommandInProgress := false;
  606.     Result := 0;
  607.     exit;
  608.   end;
  609.   repeat
  610.     TheResult := GetPOP3ServerResponse( TheReturnString );
  611.     { Put result in progress and status line }
  612.     AddProgressText( TheReturnString );
  613.     ShowProgressText( TheReturnString + #13#10 );
  614.   until (( GlobalAbortedFlag ) or ( TheResult <> TCPIP_STATUS_PRELIMINARY ));
  615.   POP3CommandInProgress := false;
  616.   if ( GlobalAbortedFlag or ( TheResult <> TCPIP_STATUS_COMPLETED )) then
  617.   begin
  618.     { Do clever C formatting trick }
  619.     TheReturnString :=
  620.      DoCStyleFormat( 'Retrieve Message %d Failed!' ,
  621.       [ TheNumber ] );
  622.     { Put result in progress and status line }
  623.     AddProgressText( TheReturnString );
  624.     ShowProgressErrorText( TheReturnString );
  625.     { Signal error }
  626.     Result := 0;
  627.     { leave }
  628.     exit;
  629.   end;
  630.   GetMem( TheReturnPChar , 514 );
  631.   try
  632.     AssignFile( TheMessageFile , TheFileName );
  633.     Rewrite( TheMessageFile );
  634.   except
  635.     MessageDlg( 'Unable to open Mail Message file ' + TheFileName + '!' ,
  636.      mtError , [mbok],0 );
  637.     Socket1.OutOfBand := 'ABOR'+#13#10;
  638.     repeat
  639.       TheResult := GetPOP3ServerResponse( TheReturnString );
  640.       { Put result in progress and status line }
  641.       AddProgressText( TheReturnString );
  642.       ShowProgressText( TheReturnString  + #13#10 );
  643.     until (( GlobalAbortedFlag ) or ( TheResult <> TCPIP_STATUS_PRELIMINARY ));
  644.     result := 0;
  645.     exit;
  646.   end;
  647.   TotalGotten := GetMessageHeader( TheHeaderSL );
  648.   for Counter_1 := 0 to TheHeaderSL.Count - 1 do
  649.    Writeln( TheMessageFile , TheHeaderSL.Strings[ Counter_1 ] );
  650.   repeat
  651.     TheResult := GetPOP3ServerExtendedResponse( TheReturnPChar );
  652.     TotalGotten := TotalGotten + StrLen( TheReturnPChar ) + 2;
  653.     if StrLen( TheReturnPChar ) > 255 then
  654.     begin
  655.       Getmem( TheHoldingPChar , 255 );
  656.       while StrLen( TheReturnPChar ) > 255 do
  657.       begin
  658.         StrCopy( TheHoldingPChar , '' );
  659.         StrMove( TheHoldingPChar , TheReturnPChar , 255 );
  660.         TheReturnPChar := TheReturnPChar + 256;
  661.         TheReturnString := StrPas( TheHoldingPChar );
  662.         Writeln( TheMessageFile , TheReturnString );
  663.       end;
  664.       StrCopy( TheHoldingPChar , '' );
  665.       StrMove( TheHoldingPChar , TheReturnPChar , StrLen( TheReturnPChar ));
  666.       TheReturnString := StrPas( TheHoldingPChar );
  667.       TheReturnString := '\' + TheReturnString;
  668.       Writeln( TheMessageFile , TheReturnString );
  669.       FreeMem( TheHoldingPChar , 255 );
  670.     end
  671.     else
  672.     begin
  673.       TheReturnString := StrPas( TheReturnPChar );
  674.       Writeln( TheMessageFile , TheReturnString );
  675.     end;
  676.   until (( GlobalAbortedFlag ) or ( TheResult = TCPIP_STATUS_COMPLETED ));
  677.   FreeMem( TheReturnPChar , 514 );
  678.   CloseFile( TheMessageFile );
  679.   Result := TotalGotten;
  680. end;
  681.  
  682. { This method Gets all the Article Listings for a newsgroup which have not been  }
  683. { Downloaded and gets them into text files. It displays Article count, # & bytes }
  684. { in the status line during the process.                                         }
  685. function TPOP3SMTPComponent.DownloadAllMessageListings(
  686.   TheEMBRecord : PEMailMailBoxRecord ) : Boolean;
  687. var WorkingList   : TList;
  688.     TheEMMRecord  : PEMailMessageRecord;
  689.     Counter_1 : Integer;
  690.     WorkingID ,
  691.     WorkingNumber : Integer;
  692.     WorkingFileName : String;
  693.     BytesToGet : Longint;
  694.     TotalMessages : Integer;
  695.     WorkingSL : TStringList;
  696.     BytesGotten : Longint;
  697. begin
  698.   Result := true;
  699.   TotalMessages := CheckAllNewMail( BytesToGet );
  700.   if TotalMessages < 0 then exit;
  701.   if TotalMessages = 0 then
  702.   begin
  703.     MessageDlg( 'No New Mail!' , mtInformation, [mbOK],0);
  704.     exit;
  705.   end;
  706.   with TheEMBRecord^ do
  707.   begin
  708.     WorkingID := MBIDNumber;
  709.     WorkingNumber := MBMaxMsgNumber;
  710.     WorkingList := TList( MBLTag );
  711.     WorkingSL := TStringList.Create;
  712.     for Counter_1 := 1 to TotalMessages do
  713.     begin
  714.       New( TheEMMRecord );
  715.       WorkingNumber := WorkingNumber + 1;
  716.       with TheEMMRecord^ do
  717.       begin
  718.         WorkingFileName := 'EM' + IntToStr( WorkingNumber );
  719.         if Length( WorkingFileName ) > 8 then WorkingFileName :=
  720.          Copy( WorkingFileName , 1 , 8 );
  721.         WorkingFileName := WorkingFileName + '.' +
  722.          IntToStr( WorkingID );
  723.         MRFileName := WorkingFileName;
  724.         WorkingFileName := MailPath + '\' + WorkingFileName;
  725.         BytesGotten := DownloadMessageListing( Counter_1 , WorkingFileName , WorkingSL );
  726.         if EMRemoteDeletionVector = 2 then DeleteMailItem( Counter_1 );
  727.         UpdateGauge( BytesGotten , BytesToGet );
  728.         MRMailBoxName      := MBName;
  729.         MRMessageSubject   := GetHeaderSubject( WorkingSL );
  730.         MRMessageRecipient := GetHeaderRecipient( WorkingSL );
  731.         MRMessageSender    := GetHeaderSender( WorkingSL );
  732.         MRCarbonCopy       := GetHeaderCarbons( WorkingSL );
  733.         MRBlindCarbonCopy  := GetHeaderBlindCarbons( WorkingSL );
  734.         MRDateTime         := GetHeaderDateTime( WorkingSL );
  735.         MRRead             := false;
  736.         MRSent             := false;
  737.         MRFileName         := ExtractFileName( WorkingFileName );
  738.         WorkingList.Add( TheEMMRecord );
  739.       end;
  740.     end;
  741.     UpdateGauge( BytesToGet , BytesToGet );
  742.     MBLTag := Longint( WorkingList );
  743.     MBMaxMsgNumber := WorkingNumber;
  744.     MBTotal       := MBTotal + TotalMessages;
  745.     MBUnReadTotal := MBUnReadTotal + TotalMessages;
  746.     Result := true;
  747.   end;
  748. end;
  749.  
  750. { This sends FTP progress text to the Inet form }
  751. procedure TPOP3SMTPComponent.ShowProgressErrorText( WhatText : String );
  752. begin
  753.  CCInetCCForm.ShowProgressErrorText( WhatText );
  754. end;
  755.  
  756. { This is a core function! It performs an FTP command and if no timeout }
  757. { return a preliminary ok.                                              }
  758. function TPOP3SMTPComponent.PerformPOP3Command(
  759.                  TheCommand        : string;
  760.            const TheArguments      : array of const ) : Integer;
  761. var TheBuffer : string; { Text buffer }
  762. begin
  763.   { If command in progress send back -1 error }
  764.   if POP3CommandInProgress then
  765.   begin
  766.     Result := -1;
  767.     exit;
  768.   end;
  769.   { Set status variable }
  770.   POP3CommandInProgress := True;
  771.   { Set global error code }
  772.   GlobalErrorCode := 0;
  773.   { Format output string }
  774.   TheBuffer := Format( TheCommand , TheArguments );
  775.   { Preset failure code }
  776.   Result := TCPIP_STATUS_FATAL_ERROR;
  777.   { If invalid socket or no connection abort }
  778.   if ( Socket1.TheSocket = INVALID_SOCKET ) or not Connection_Established then
  779.    exit;
  780.   { Send the buffer plus EOL chars }
  781.   Socket1.StringData := TheBuffer + #13#10;
  782.   { if abort due to timeout or other error exit }
  783.   if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then exit;
  784.   { Otherwise return preliminary code }
  785.   Result := TCPIP_STATUS_PRELIMINARY;
  786. end;
  787.  
  788. { This function gets up to 255 chars of data plus a return code from FTP serv }
  789. function TPOP3SMTPComponent.GetPOP3ServerResponse(
  790.           var ResponseString : String ) : integer;
  791. var
  792.   { Buffer string for response line }
  793.   TheBuffer     : string;
  794.   { Pointer to the response string }
  795.   BufferPointer : array[0..255] of char absolute TheBuffer;
  796.   { Character to check for response code }
  797.   ResponseChar   : char;
  798.   { Pointers into returned string }
  799.   TheIndex ,
  800.   TheLength     : integer;
  801.   { Control variable }
  802.   LeftoversInPan ,
  803.   Finished      : Boolean;
  804. begin
  805.   { Preset fatal error }
  806.   Result := TCPIP_STATUS_FATAL_ERROR;
  807.   { Start loop control }
  808.   LeftoversInPan := false;
  809.   Finished := false;
  810.   repeat
  811.     { Do a peek }
  812.     TheBuffer := Socket1.PeekData;
  813.     { If timeout or other error exit }
  814.     if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then exit;
  815.     { Find end of line character }
  816.     TheIndex := Pos( #10 , TheBuffer );
  817.     if TheIndex = 0 then
  818.     begin
  819.       TheIndex := Pos( #13 , TheBuffer );
  820.       if TheIndex = 0 then
  821.       begin
  822.         TheIndex := Pos( #0 , TheBuffer );
  823.         if TheIndex = 0 then
  824.         begin
  825.           TheIndex := Length( TheBuffer );
  826.           LeftoversInPan := True;
  827.           LeftoverText := LeftoverText + TheBuffer;
  828.           LeftoversOnTable := false;
  829.         end;
  830.       end;
  831.     end;
  832.     { If an end of line then process the line }
  833.     if TheIndex > 0 then
  834.     begin
  835.       { Get length of string }
  836.       TheLength := TheIndex;
  837.       { Receive actual data }
  838.       Socket1.CCSockReceive( Socket1.TheSocket   ,
  839.                              @BufferPointer[ 1 ] ,
  840.                              TheLength              );
  841.       { Abort if timeout or error }
  842.       if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 )) then exit;
  843.       { Put in the length byte }
  844.       BufferPointer[ 0 ] := Chr( TheLength );
  845.       if LeftOversOnTable then
  846.       begin
  847.         LeftOversOnTable := false;
  848.         ResponseString := LeftoverText + TheBuffer;
  849.         TheBuffer := ResponseString;
  850.         LeftoverText := '';
  851.       end;
  852.       if LeftoversInPan then
  853.       begin
  854.         LeftoversInPan := false;
  855.         LeftoversOnTable := true;
  856.       end;
  857.       { Get first number character }
  858.       ResponseChar := TheBuffer[ 1 ];
  859.       { Get the value of the number from 1 to 5 }
  860.       if (( ResponseChar = '+' ) or ( ResponseChar = '-' )) then
  861.       begin
  862.         Finished := true;
  863.         if ResponseChar = '+' then Result := TCPIP_STATUS_COMPLETED
  864.          else Result := TCPIP_STATUS_FATAL_ERROR;
  865.       end;
  866.     end
  867.     else
  868.     begin
  869.     end;
  870.   until ( Finished and ( not LeftoversOnTable ));
  871.   { Return buffer as response string }
  872.   ResponseString := TheBuffer;
  873.   ResponseString := Copy( ResponseString , 1, Length( ResponseString ) - 2 );
  874. end;
  875.  
  876. { Boilerplate error routine }
  877. procedure TPOP3SMTPComponent.POP3SMTPSocketsErrorOccurred( Sender     : TObject;
  878.                                                  ErrorCode  : Integer;
  879.                                                  TheMessage : String   );
  880. begin
  881.   CCInetCCForm.SocketsErrorOccurred( Sender,ErrorCode,TheMessage );
  882. end;
  883.  
  884. { This is the POP3SMTP components POP3 initial connection routine }
  885. function TPOP3SMTPComponent.EstablishPOP3Connection(
  886.           PCRPointer : PConnectionsRecord ) : Boolean;
  887. var TheReturnString : String;  { Internal string holder }
  888.     TheResult       : Integer; { Internal int holder    }
  889. begin
  890.   { Set default FTP Port value }
  891.   Socket1.PortName := '110';
  892.   { Get the ip address from the record }
  893.   Socket1.IPAddressName := PCRPointer^.CIPAddress;
  894.   { Set blocking mode }
  895.   Socket1.AsynchMode := False;
  896.   { Clear condition variables }
  897.   GlobalErrorCode := 0;
  898.   GlobalAbortedFlag := false;
  899.   { Actually attempt to connect }
  900.   Socket1.CCSockConnect;
  901.   { Check if connected }
  902.   if (( GlobalAbortedFlag ) or ( GlobalErrorCode <> 0 ) or
  903.       ( Socket1.TheSocket = INVALID_SOCKET )) then
  904.   begin { Didn't connect; signal error and abort }
  905.     { Do clever C formatting trick }
  906.     TheReturnString :=
  907.      DoCStyleFormat( 'POP3 Host %s Connection Failed!' ,
  908.       [ PCRPointer^.CIPAddress ] );
  909.     { Put result in progress and status line }
  910.     AddProgressText( TheReturnString );
  911.     ShowProgressErrorText( TheReturnString );
  912.     { Signal error }
  913.     Result := False;
  914.     { leave }
  915.     exit;
  916.   end
  917.   else
  918.   begin
  919.     Connection_Established := true;
  920.     { Signal successful connection }
  921.     TheReturnString := DoCStyleFormat(
  922.       'Connected on Local port: %s with IP: %s',
  923.       [ Socket1.GetSocketPort( Socket1.TheSocket ),
  924.         Socket1.GetSocketIPAddress( Socket1.TheSocket )]);
  925.     { Put result in progress and status line }
  926.     CCINetCCForm.AddProgressText( TheReturnString );
  927.     CCINetCCForm.ShowProgressText( TheReturnString );
  928.     TheReturnString := DoCStyleFormat(
  929.      'Connected to Remote port: %s with IP: %s',
  930.       [ Socket1.GetSocketPeerPort( Socket1.TheSocket ),
  931.         Socket1.GetSocketPeerIPAddress( Socket1.TheSocket )]);
  932.     { Put result in progress and status line }
  933.     CCINetCCForm.AddProgressText( TheReturnString );
  934.     CCINetCCForm.ShowProgressText( TheReturnString );
  935.     TheReturnString := DoCStyleFormat( 'Successfully connected to %s',
  936.      [ Socket1.IPAddressName ]);
  937.     { Put result in progress and status line }
  938.     CCINetCCForm.AddProgressText( TheReturnString );
  939.     CCINetCCForm.ShowProgressText( TheReturnString );
  940.     repeat
  941.       TheResult := GetPOP3ServerResponse( TheReturnString );
  942.       { Put result in progress and status line }
  943.       AddProgressText( TheReturnString );
  944.       ShowProgressText( TheReturnString );
  945.     until (( GlobalAbortedFlag ) or ( TheResult <> TCPIP_STATUS_PRELIMINARY ));
  946.     if ( GlobalAbortedFlag or ( TheResult <> TCPIP_STATUS_COMPLETED )) then
  947.     begin
  948.       { Do clever C formatting trick }
  949.       TheReturnString :=
  950.        DoCStyleFormat( 'POP3 Host %s Connection Failed!' ,
  951.         [ PCRPointer^.CIPAddress ] );
  952.       { Put result in progress and status line }
  953.       AddProgressText( TheReturnString );
  954.       ShowProgressErrorText( TheReturnString );
  955.       { Signal error }
  956.       Result := False;
  957.       { leave }
  958.       exit;
  959.     end
  960.     else Result := true; { Signal no problem }
  961.   end;
  962. end;
  963.  
  964. { This sends FTP progress text to the Inet form }
  965. procedure TPOP3SMTPComponent.AddProgressText( WhatText : String );
  966. begin
  967.   CCInetCCForm.AddProgressText( WhatText );
  968. end;
  969.  
  970. { This sends FTP progress text to the Inet form }
  971. procedure TPOP3SMTPComponent.ShowProgressText( WhatText : String );
  972. begin
  973.   CCInetCCForm.ShowProgressText( WhatText );
  974. end;
  975.  
  976. { This is a clever c-style formatting trick }
  977. function TPOP3SMTPComponent.DoCStyleFormat(
  978.                 TheText      : string;
  979.           const TheArguments : array of const ) : String;
  980. begin
  981.   Result := Format( TheText , TheArguments ) + #13#10;
  982. end;
  983.  
  984. { This is the FTP components USER login routine }
  985. function TPOP3SMTPComponent.LoginUser(
  986.           PCRPointer : PConnectionsRecord ) : Boolean;
  987. var TheReturnString : String;  { Internal string holder }
  988.     TheResult       : Integer; { Internal int holder    }
  989. begin
  990.   TheReturnString :=
  991.    DoCStyleFormat( 'USER %s' ,
  992.     [ PCRPointer^.CUserName ] );
  993.   { Put result in progress and status line }
  994.   AddProgressText( TheReturnString );
  995.   ShowProgressText( TheReturnString );
  996.   { Begin login sequence with user name }
  997.   TheResult := PerformPOP3Command( 'USER %s',
  998.                                   [ PCRPointer^.CUserName ] );
  999.   if TheResult <> TCPIP_STATUS_PRELIMINARY then
  1000.   begin
  1001.     POP3CommandInProgress := false;
  1002.     Result := false;
  1003.     exit;
  1004.   end;
  1005.   repeat
  1006.     TheResult := GetPOP3ServerResponse( TheReturnString );
  1007.     { Put result in progress and status line }
  1008.     AddProgressText( TheReturnString );
  1009.     ShowProgressText( TheReturnString + #13#10 );
  1010.   until (( GlobalAbortedFlag ) or ( TheResult <> TCPIP_STATUS_PRELIMINARY ));
  1011.   POP3CommandInProgress := false;
  1012.   if ( GlobalAbortedFlag or ( TheResult <> TCPIP_STATUS_COMPLETED )) then
  1013.   begin
  1014.     { Do clever C formatting trick }
  1015.     TheReturnString :=
  1016.      DoCStyleFormat( 'POP3 Host %s Login Failed!' ,
  1017.       [ PCRPointer^.CIPAddress ] );
  1018.     { Put result in progress and status line }
  1019.     AddProgressText( TheReturnString );
  1020.     ShowProgressErrorText( TheReturnString );
  1021.     { Signal error }
  1022.     Result := False;
  1023.     { leave }
  1024.     exit;
  1025.   end
  1026.   else Result := true; { Signal no problem }
  1027. end;
  1028.  
  1029. { This is the FTP components PASSWORD routine }
  1030. function TPOP3SMTPComponent.SendPassword(
  1031.           PCRPointer : PConnectionsRecord ) : Boolean;
  1032. var TheReturnString : String;  { Internal string holder }
  1033.     TheResult       : Integer; { Internal int holder    }
  1034. begin
  1035.   TheReturnString := 'PASS XXXXXX' + #13#10;
  1036.   { Put result in progress and status line }
  1037.   AddProgressText( TheReturnString );
  1038.   ShowProgressText( TheReturnString );
  1039.   { Send Password sequence }
  1040.   TheResult := PerformPOP3Command( 'PASS %s',
  1041.                                   [ PCRPointer^.CPassword ] );
  1042.   if TheResult <> TCPIP_STATUS_PRELIMINARY then
  1043.   begin
  1044.     Result := false;
  1045.     POP3CommandInProgress := false;
  1046.     exit;
  1047.   end;
  1048.   repeat
  1049.     TheResult := GetPOP3ServerResponse( TheReturnString );
  1050.     { Put result in progress and status line }
  1051.     AddProgressText( TheReturnString );
  1052.     ShowProgressText( TheReturnString + #13#10 );
  1053.   until (( GlobalAbortedFlag ) or ( TheResult <> TCPIP_STATUS_PRELIMINARY ));
  1054.   POP3CommandInProgress := false;
  1055.   if ( GlobalAbortedFlag or ( TheResult <> TCPIP_STATUS_COMPLETED )) then
  1056.   begin
  1057.     { Do clever C formatting trick }
  1058.     TheReturnString :=
  1059.      DoCStyleFormat( 'POP3 Host %s Login Failed!' ,
  1060.       [ PCRPointer^.CIPAddress ] );
  1061.     { Put result in progress and status line }
  1062.     AddProgressText( TheReturnString );
  1063.     ShowProgressErrorText( TheReturnString );
  1064.     { Signal error }
  1065.     Result := False;
  1066.     { leave }
  1067.     exit;
  1068.   end
  1069.   else Result := true; { Signal no problem }
  1070. end;
  1071.  
  1072. { This is the FTP component constructor; it creates 2 sockets }
  1073. constructor TPOP3SMTPComponent.Create( AOwner : TComponent );
  1074. begin
  1075.   { do inherited create }
  1076.   inherited Create( AOwner );
  1077.   { Create sockets, put in their parents, and error procs }
  1078.   Socket1 := TCCSocket.Create( Self );
  1079.   Socket1.Parent := Self;
  1080.   Socket1.OnErrorOccurred := POP3SMTPSocketsErrorOccurred;
  1081.   { Set up booleans }
  1082.   Connection_Established := false;
  1083.   POP3CommandInProgress := false;
  1084. end;
  1085.  
  1086. { This is the FTP component destructor; it frees 2 sockets }
  1087. destructor TPOP3SMTPComponent.Destroy;
  1088. begin
  1089.   { Free the sockets }
  1090.   Socket1.Free;
  1091.   { and call inherited }
  1092.   inherited Destroy;
  1093. end;
  1094.  
  1095. { This is the POP3 components QUIT routine }
  1096. function TPOP3SMTPComponent.POP3Disconnect : Boolean;
  1097. var TheReturnString : String;  { Internal string holder }
  1098.     TheResult       : Integer; { Internal int holder    }
  1099. begin
  1100.   TheReturnString :=
  1101.    DoCStyleFormat( 'QUIT' ,
  1102.     [ nil ] );
  1103.   { Put result in progress and status line }
  1104.   AddProgressText( TheReturnString );
  1105.   ShowProgressText( TheReturnString );
  1106.   { Begin login sequence with user name }
  1107.   PerformPOP3Command( 'QUIT', [ nil ] );
  1108.   repeat
  1109.     TheResult := GetPOP3ServerResponse( TheReturnString );
  1110.     { Put result in progress and status line }
  1111.     AddProgressText( TheReturnString );
  1112.     ShowProgressText( TheReturnString + #13#10 );
  1113.   until (( GlobalAbortedFlag ) or ( TheResult <> TCPIP_STATUS_PRELIMINARY ));
  1114.   POP3CommandInProgress := false;
  1115.   if ( GlobalAbortedFlag or ( TheResult <> TCPIP_STATUS_COMPLETED )) then
  1116.   begin
  1117.     { Do clever C formatting trick }
  1118.     TheReturnString :=
  1119.      DoCStyleFormat( 'EMail Host Connection Failed!' ,
  1120.       [ nil ] );
  1121.     { Put result in progress and status line }
  1122.     AddProgressText( TheReturnString );
  1123.     ShowProgressErrorText( TheReturnString );
  1124.     { Signal error }
  1125.     Result := False;
  1126.     { leave }
  1127.     exit;
  1128.   end
  1129.   else Result := true; { Signal no problem }
  1130. end;
  1131.  
  1132.  
  1133. procedure TPOP3SMTPComponent.UpdateGauge( BytesFinished , TotalToHandle : longint );
  1134. begin
  1135.   CCInetCCForm.UpdateMailGauge( BytesFinished , TotalToHandle );
  1136. end;
  1137.  
  1138. end.
  1139.